package com.baiytfp.hf.HFDataExchange.common.base.aop;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.baiytfp.hf.HFDataExchange.common.base.anotation.Auth;
import com.baiytfp.hf.HFDataExchange.common.utils.CommonUtil;
import com.baiytfp.hf.HFDataExchange.common.utils.auth.AuthUtils;
import com.baiytfp.hf.baiytfp.framework.shiro.ShiroUtil;
import com.baiytfp.hf.baiytfp.hfutils.HFResponse;



@Component
@Aspect
public class AuthInterceptor {
	
	String[] funcCode = null;
	boolean isPage = true;
	boolean checkMenu = false;
	String[] dataRight = null;
	
	boolean useInterceptor = false;
	
	ProceedingJoinPoint pjp = null;
	
	Object[] params = null;
	HttpServletResponse response =null;
	HttpServletRequest request = null;
	
	String userCode = null;
	
	int dataRight_index = -1;
	
	@Pointcut("@annotation(com.baiytfp.hf.HFDataExchange.common.base.anotation.Auth)")
    public  void controllerAspect() {    
   }    
	
	@Around("controllerAspect()")
	public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
		
		initParams(pjp);
		Object rs = null;
		if(useInterceptor) {
			rs = doWork();
		}else {
			rs = pjp.proceed();
		}
		return rs;
	}
	
	
	private Object doWork() throws Throwable {
		
		Map rs = new HashMap<>();
		String errorMsg = "暂无权限！请联系管理员";
		
		
		
		// TODO check menu
		if(!AuthUtils.isAdmin(userCode) && checkMenu ) {
			RequestMapping parent = pjp.getTarget().getClass().getAnnotation(RequestMapping.class);
			RequestMapping child = getTargetMethod().getAnnotation(RequestMapping.class);
			
			if( parent==null || child ==null || !AuthUtils.canDoMenu(userCode, parent.value()[0]+child.value()[0]+".do")) {
				if(!isPage) {
					if(response != null) {
						HFResponse.getIstance().returnResult(response, -1, errorMsg, null);
						return null;
					}else {
						rs.put("state", -1);
				        rs.put("message", errorMsg);
				        rs.put("success", false);
						return rs;
					}
				}else {
					return new ModelAndView("index/unauthorized");
				}
			}
		}
			
		// TODO check func
		/*if( !AuthUtils.isAdmin(userCode) && funcCode.length>0 && !CommonUtil.isEmpty(funcCode[0]) ) {
			if(!AuthUtils.canDoFunc(userCode, funcCode)) {
				if(!isPage) {
					if(response != null) {
						HFResponse.getIstance().returnResult(response, -1, errorMsg, null);
						return null;
					}else {
						rs.put("state", -1);
				        rs.put("message", errorMsg);
				        rs.put("success", false);
						return rs;
					}
				}else {
					return new ModelAndView("index/unauthorized");
				}
			}
		}*/
		
		// TODO check data
		
		return pjp.proceed(params);
	}


	private void initParams(ProceedingJoinPoint pjp) throws Exception {
		clear();
		this.pjp = pjp;
		Method method = getTargetMethod();
		Object[] rs = method.getAnnotations();
		Auth auth = method.getAnnotation(Auth.class);
		if( null != auth  ) {
			this.checkMenu = auth.checkMenu();
			this.funcCode = auth.func();
			this.isPage = auth.isPage();
			this.dataRight = auth.dataRight();
			
			params = pjp.getArgs();
			for(int i=0;params!=null&&i<params.length;i++) {
				if(params[i] instanceof HttpServletRequest ) {
					this.request = (HttpServletRequest) params[i];
				}
				if(params[i] instanceof HttpServletResponse ) {
					this.response = (HttpServletResponse) params[i];
				}
				if(params[i] instanceof Map ) {
					dataRight_index = i;
				}
			}
			
			this.userCode = ShiroUtil.getUserCode();
			this.useInterceptor = true;
		}
	}
	
	private Method getTargetMethod() {
		Signature sig = pjp.getSignature();
		if (sig instanceof MethodSignature) {
		  	 return ((MethodSignature)sig).getMethod();
		}
		return null;
	}
	
	private void clear(){
		 dataRight_index=-1;
		 response =null;
		 request = null;
		
		 funcCode = null;
		 isPage = true;
		 checkMenu = false;
		 dataRight = null;
		
		 useInterceptor = false;
		
		 pjp = null;
		
		 params = null;
		 response =null;
		 request = null;
		
		 userCode = null;
	}
}
